﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="TabItemsControl.cs" company="">
//   
// </copyright>
// <summary>
//   The tab items control.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Libium.Controls
{
    using System;
    using System.Drawing;
    using System.Windows.Forms;

    /// <summary>
    /// The tab items control.
    /// </summary>
    public partial class TabItemsControl : ItemsControl
    {
        #region Fields

        /// <summary>
        /// The _drag index.
        /// </summary>
        private int _dragIndex = -1;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="TabItemsControl"/> class.
        /// </summary>
        public TabItemsControl()
        {
            InitializeComponent();
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// The add item view.
        /// </summary>
        /// <param name="typeName">
        /// The type name.
        /// </param>
        /// <param name="itemControl">
        /// The item control.
        /// </param>
        /// <returns>
        /// The <see cref="Control"/>.
        /// </returns>
        public override Control AddItemView(string typeName, Control itemControl)
        {
            var page = new TabPage();
            itemControl.Dock = DockStyle.Fill;
            page.Controls.Add(itemControl);
            TabControl.TabPages.Add(page);
				page.VisibleChanged += page_VisibleChanged;
            return page;
        }

		  void page_VisibleChanged(object sender, EventArgs e)
		  {
			  if (((TabPage)sender).Visible)
			  {
				  StackItemsControl c = ((TabPage)sender).Controls[0] as StackItemsControl;
				  if (c != null)
				  {
					  c.EnsureScrollVisibleIfNeeded();
				  }
			  }
		  }

        /// <summary>
        /// The clear.
        /// </summary>
        public override void Clear()
        {
            TabControl.TabPages.Clear();
        }

        /// <summary>
        /// The delete item view.
        /// </summary>
        /// <param name="view">
        /// The view.
        /// </param>
        public override void DeleteItemView(Control view)
        {
            foreach (TabPage tabPage in TabControl.TabPages)
            {
                if (tabPage.Controls[0] == view)
                {
                    TabControl.TabPages.Remove(tabPage);
                    break;
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// The get tab page index under cursor.
        /// </summary>
        /// <returns>
        /// The <see cref="int"/>.
        /// </returns>
        private int GetTabPageIndexUnderCursor()
        {
            var position = TabControl.PointToClient(MousePosition);
            for (var index = 0; index < TabControl.TabCount; ++index)
            {
                if (TabControl.GetTabRect(index).Contains(position))
                {
                    return index;
                }
            }

            return -1;
        }

        /// <summary>
        /// The tab control_ drag over.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void TabControl_DragOver(object sender, DragEventArgs e)
        {
            var index = GetTabPageIndexUnderCursor();
            if (index == -1)
            {
                return;
            }

            if (index == _dragIndex)
            {
                return;
            }

            _dragIndex = index;
            Timer.Start();
        }

        /// <summary>
        /// The timer_ tick.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void Timer_Tick(object sender, EventArgs e)
        {
            Timer.Stop();
            var index = GetTabPageIndexUnderCursor();
            if (index == _dragIndex)
            {
                TabControl.SelectedIndex = index;
            }
        }

        #endregion

        private Font _selectedPageFont;

        public Font SelectedPageFont
        {
            get
            {
                if (_selectedPageFont == null)
                {
                    _selectedPageFont = (Font)Font.Clone();
                }
                return _selectedPageFont;
            }
            set
            {
                _selectedPageFont = value;
            }
        }

        private void TabControl_DrawItem(object sender, DrawItemEventArgs e)
        {
            var page = TabControl.TabPages[e.Index];
            var textBrush = new SolidBrush(ForeColor);
            var rectangle = TabControl.GetTabRect(e.Index);

            var stringFormat = new StringFormat
                { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center };

            e.Graphics.DrawString(
                page.Text,
                Convert.ToBoolean(e.State & DrawItemState.Selected) ? SelectedPageFont : Font,
                textBrush,
                rectangle,
                stringFormat);

            textBrush.Dispose();
        }
    }
}